package com.yuanmei.views;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.yuanmei.datas.NetEaseWebSource;
import com.yuanmei.model.AmountStat;
import com.yuanmei.model.PriceStat;
import com.yuanmei.datas.SinaWebSource;
import com.yuanmei.model.TickQuote;
import com.yuanmei.common.Utils;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

public class TickQuoteStatActivity extends Activity implements PriceStatAdapter.ItemClickListener {
    private final static String TAG = TickQuoteStatActivity.class.getSimpleName();
    protected static final int MSG_UPDATE_CHARTS = 1;
    protected static final int MSG_EMPTY_DATA = 2;

    private String mName;
    private String mNetEaseCode;
    private Boolean mIsMarketIndex;
    private Date mTickDate;
    private int mTickIDate;
    private List<TickQuote> mTickQuotes;

    private RecyclerView mPriceStatView;
    private RecyclerView mStatBigQuotesView;
    private RecyclerView mStatLittleQuotesView;
    private RecyclerView mBigQuotesListView;

    private TextView mTvSeekDetail;
    private TextView mTvStatStockInfo;

    private void addNewStatToMap(
            HashMap<Float, PriceStat> map,
            TickQuote quote) {
        float price = quote.getPrice();
        float amount = quote.getAmount();
        if (map.containsKey(price)) {
            PriceStat stat = map.get(price);
            float newAmount = stat.getAmount() + amount;
            stat.setAmount(newAmount);
            stat.incQuoteCount();
            stat.addQuoteToDetailList(quote);
        } else {
            PriceStat stat = new PriceStat(price, amount);
            stat.addQuoteToDetailList(quote);
            map.put(price, stat);
        }
    }

    private List<PriceStat> mPriceStatList;
    List<TickQuote> mDetailBigTickQuoteList = new ArrayList<>();
    List<TickQuote> mDetailLittleTickQuoteList = new ArrayList<>();

    private float mBigQuoteScale = 0.2f;
    private float mDivideQuoteAmount;
    private float mDivideQuoteVolume;
    List<TickQuote> mBigQuoteList = new ArrayList<>();

    private void rebuildData() {
        HashMap<Float, AmountStat> amountStatMap = new HashMap<>();
        HashMap<Float, PriceStat> priceStatMap = new HashMap<>();
        float maxQuoteAmount = 0, maxQuoteVolume = 0;
        float totalAmount = 0;
        float minQuoteAmount = Float.MAX_VALUE, minQuoteVolume = Float.MAX_VALUE;
        for (int i = 0; i < mTickQuotes.size(); i++) {
            TickQuote quote = mTickQuotes.get(i);
            addNewStatToMap(priceStatMap, quote);

            float amount = quote.getAmount();
            float volume = quote.getVolume();
            totalAmount += amount;
            maxQuoteAmount = Math.max(amount, maxQuoteAmount);
            minQuoteAmount = Math.min(amount, minQuoteAmount);
            maxQuoteVolume = Math.max(volume, maxQuoteVolume);
            minQuoteVolume = Math.min(volume, minQuoteVolume);
            if (amountStatMap.containsKey(amount)) {
                AmountStat stat = amountStatMap.get(amount);
                int newCount = stat.getCount() + 1;
                stat.setCount(newCount);
            } else {
                amountStatMap.put(amount, new AmountStat(amount, volume, 1));
            }
        }

        List<AmountStat> amountStatList = new ArrayList<>(amountStatMap.values());
        Collections.sort(amountStatList,
                (self, other) -> (Float.compare(other.getAmount(), self.getAmount())));
        mDivideQuoteAmount = 0;
        float bigSum = 0;
        float scaleAmount = mBigQuoteScale * totalAmount;
        for (int i = 0; i < amountStatList.size(); i++) {
            float amount = amountStatList.get(i).getAmount();
            bigSum += amount * amountStatList.get(i).getCount();
            if (bigSum >= scaleAmount) {
                mDivideQuoteAmount = amountStatList.get(i).getAmount();
                mDivideQuoteVolume = amountStatList.get(i).getVolume();
                break;
            }
        }

        mBigQuoteList.clear();
        for (TickQuote tq: mTickQuotes) {
            if (tq.getAmount() > mDivideQuoteAmount) {
                mBigQuoteList.add(tq);
            }
        }
        // 顺排
        Collections.sort(mBigQuoteList, (self, other) -> (Float.compare(self.getTick(), other.getTick())));

        mPriceStatList = new ArrayList<>(priceStatMap.values());
        for (PriceStat ps: mPriceStatList) {
            float amountPct = ps.getAmount() * 100.0f / totalAmount;
            ps.setAmountPct(amountPct);
        }
        // 逆排
        Collections.sort(mPriceStatList, (self, other) -> (Float.compare(other.getAmount(), self.getAmount())));
        rebuiltDetailTickQuoteList();
    }

    private void rebuiltDetailTickQuoteList() {
        int pos = 0;
        if (mPriceStatAdapter != null) {
            pos = mPriceStatAdapter.getCurrentClickPosition();
        }
        List<TickQuote> posList = mPriceStatList.get(pos).getDetailQuoteList();
        mDetailBigTickQuoteList.clear();
        mDetailLittleTickQuoteList.clear();
        for (TickQuote tq : posList) {
            if (tq.getAmount() >= mDivideQuoteAmount) {
                mDetailBigTickQuoteList.add(tq);
            } else {
                mDetailLittleTickQuoteList.add(tq);
            }
        }
    }

    private void refreshTickQuoteView(RecyclerView rv,
                                      List<TickQuote> tl) {
        if (rv.getAdapter() == null) {
            rv.setAdapter(new TickQuoteListAdapter(tl));
            rv.setLayoutManager(new LinearLayoutManager(this,
                    LinearLayoutManager.VERTICAL, false));
        } else {
            TickQuoteListAdapter tql = (TickQuoteListAdapter) rv.getAdapter();
            tql.setTickQuoteList(tl);
        }
    }

    private PriceStatAdapter mPriceStatAdapter;

    private void refreshViews() {
        if (mPriceStatAdapter == null) {
            mPriceStatAdapter = new PriceStatAdapter(mPriceStatList);
            mPriceStatView.setAdapter(mPriceStatAdapter);
            mPriceStatView.setLayoutManager(new LinearLayoutManager(this,
                    LinearLayoutManager.VERTICAL, false));
            mPriceStatAdapter.setClickListener(this);
            mPriceStatAdapter.setCurrentClickPosition(0);
        } else {
            mPriceStatAdapter.setPriceStatList(mPriceStatList);
//            mPriceStatAdapter.setDivideAmount(mDivideQuoteAmount);
        }
        refreshTickQuoteView(mStatBigQuotesView, mDetailBigTickQuoteList);
        refreshTickQuoteView(mStatLittleQuotesView, mDetailLittleTickQuoteList);
        refreshTickQuoteView(mBigQuotesListView, mBigQuoteList);

        mTvSeekDetail.setText(String.format(Locale.CHINA,
                "大单比例:%.2f%% 分界单笔:%.2f万 %d手",
                mBigQuoteScale * 100, mDivideQuoteAmount / 1000,
                (int) mDivideQuoteVolume / 100
        ));
    }

    @Override
    public void onItemClick(RecyclerView.Adapter adapter, View view, int position) {
        if (adapter == mPriceStatAdapter) {
            mPriceStatAdapter.setCurrentClickPosition(position);
            mPriceStatAdapter.notifyDataSetChanged();
            rebuiltDetailTickQuoteList();
            refreshTickQuoteView(mStatBigQuotesView, mDetailBigTickQuoteList);
            refreshTickQuoteView(mStatLittleQuotesView, mDetailLittleTickQuoteList);
        }
    }

    private static class StatActivityMessageHandler extends Handler {
        private final WeakReference<TickQuoteStatActivity> mWeakStatActivity;

        private StatActivityMessageHandler(TickQuoteStatActivity tsActivity) {
            mWeakStatActivity = new WeakReference<>(tsActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            TickQuoteStatActivity statActivity = mWeakStatActivity.get();
            if (statActivity == null)
                return;

            switch (msg.what) {
                case MSG_UPDATE_CHARTS:
                    statActivity.refreshViews();
                    break;
                case MSG_EMPTY_DATA:
                    Toast.makeText(statActivity,
                            "获取" + statActivity.mName + "(" + statActivity.mNetEaseCode.substring(1) + ") 分时数据失败 ",
                            Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    }

    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mName = getIntent().getStringExtra("Name");
        mNetEaseCode = getIntent().getStringExtra("NetEaseCode");
        mIsMarketIndex = getIntent().getBooleanExtra("IsMarketIndex", false);
        mTickIDate = getIntent().getIntExtra("XDate", 19700101);
        mTickDate = Utils.getDateFromIDate(mTickIDate);
//        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_stat_tick_quote);

        mTvStatStockInfo = findViewById(R.id.stat_stock_info);
        mTvStatStockInfo.setText(String.format(Locale.CHINA, "%s %s %d", mName, mNetEaseCode.substring(1), mTickIDate));
        mPriceStatView = findViewById(R.id.price_stat_ov);
        mStatBigQuotesView = findViewById(R.id.pricel_big_details);
        mStatLittleQuotesView = findViewById(R.id.price_little_quotes);
        mBigQuotesListView = findViewById(R.id.big_quotes_list);

        mTvSeekDetail = findViewById(R.id.seek_detail);

        SeekBar seek = findViewById(R.id.scale_seek_bar);
        seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    mBigQuoteScale = (float) progress / (float) seekBar.getMax();
                    new Thread(() -> {
                        rebuildData();
                        Message.obtain(mHandler, MSG_UPDATE_CHARTS).sendToTarget();
                    }).start();
                }
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
        mBigQuoteScale = (float) seek.getProgress() / (float) seek.getMax();

        mHandler = new StatActivityMessageHandler(this);
        new Thread(() -> {
            mTickQuotes = null;
            if (mTickIDate < Utils.getCurrentIDate()) {
                // 腾讯只能取历史分时，没有当日分时
                mTickQuotes = Utils.getHistoryTickData(mNetEaseCode, mTickDate);
            }

            if (mTickQuotes == null || mTickQuotes.size() <= 0) {
                if (mIsMarketIndex) {
                    mTickQuotes = NetEaseWebSource.getRealTimeTickData(mNetEaseCode, mTickDate);
                } else {
                    mTickQuotes = SinaWebSource.getRealTimeTickData(mNetEaseCode, mTickDate);
                }
            }
            if (mTickQuotes == null || mTickQuotes.size() <= 0) {
                Message.obtain(mHandler, MSG_EMPTY_DATA).sendToTarget();
            } else {
                rebuildData();
                Message.obtain(mHandler, MSG_UPDATE_CHARTS).sendToTarget();
            }
        }).start();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}
